package cc.jt.rl;

import java.util.Arrays;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import redis.clients.jedis.JedisCluster;

@Slf4j
public class RedisRateLimiter {

  private final static Pair<Boolean, String> PairTrue = Pair.of(true, null);

  private final JedisCluster jedisCluster;

  private String luaScript = null;
  private final RateLimiterConfig rateLimiterConfig;

  @SneakyThrows
  public RedisRateLimiter(RateLimiterConfig rateLimiterConfig, JedisCluster jedisCluster) {
    this.rateLimiterConfig = rateLimiterConfig;
    this.jedisCluster = jedisCluster;
    this.luaScript = ScriptUtil.getScript("counter_limit.lua");
  }

  private Pair<Boolean, String> fixedWindowsTryAcquire(String resource) {
    Integer maxPermits = rateLimiterConfig.get(resource);
    if (maxPermits == null) {
      // 不需要限流
      return PairTrue;
    }

    try {
      Object result = jedisCluster.eval(luaScript,
          Arrays.asList(resource),
          Arrays.asList(String.valueOf(maxPermits), "1000")
      );
      boolean isAcquire = result != null && 0 != (Long) result;
      if (!isAcquire) {
        return Pair.of(false, String.format("超过 QPS 调用量 %s", maxPermits));
      }
    }
    catch (Exception e) {
      log.error("RateLimiter JedisCluster Error {}", resource, e);
    }
    return PairTrue;
  }
}
